﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
#region using for special implements
using System.Web.Mvc;
using System.Text;
using Com.ProjectA.BusinessLogic;
using Com.ProjectA.DAO;
#endregion using for special implements
namespace Com.ProjectA.FAMvc.MvcHtmlHelper
{
    public class HtmlMvcHelpers
    {
        #region Common Function
        /// <summary>
        /// Render pedigree chart common function
        /// </summary>
        /// <param name="strCd">Person code string. At the initial time, person code will be 01</param>
        /// <param name="ls">List of person</param>
        /// <param name="lsB">List of person code to keep track which person was already in pedigree chart</param>
        /// <param name="strBuilder">render pedigree string builder</param>
        /// <param name="intGenCount">The number of generation that system rendered. Maximum of this number is 10 default</param>
        /// <param name="intMaxGenDepth">The maximum of generation depth. Default is 10</param>
        /// <returns>pedigree</returns>
        private static string RenderPedigree(string strCd, List<DAOPerson> ls, List<string> lsB, StringBuilder strBuilder, int intGenCount, int intMaxGenDepth = 10)
        {
            if (intGenCount == intMaxGenDepth)
            {
                return strBuilder.ToString();
            }
            if (strCd.Equals("01"))
            {
                strBuilder.AppendLine("<ul>");
                strBuilder.AppendFormat("<li><a href='#divPedigree' name='{0}'>{1}</a>", 0, strCd);
            }
            bool end = false;
            foreach (DAOPerson person in ls)
            {
                if (BLGenealogic.IsXDescendant(strCd, person.person_code, 1))
                {
                    if (!lsB.Contains(strCd))
                    {
                        lsB.Add(strCd);
                    }
                    if (!end)
                    {
                        strBuilder.AppendLine("<ul>");
                    }
                    strBuilder.AppendFormat("<li><a href='#divPedigree' name='{0}'>{1}</a>", person.person_id, person.person_code);
                    RenderPedigree(person.person_code, ls, lsB, strBuilder, intGenCount + 1, 10);
                    strBuilder.AppendLine("</li>");
                    end = true;
                }
            }
            if (end)
            {
                strBuilder.AppendLine("</ul>");
            }
            if (strCd.Equals("01"))
            {
                strBuilder.AppendLine("</li>");
                strBuilder.AppendLine("</ul>");
            }
            return strBuilder.ToString();
        }

        /// <summary>
        /// Render pedigree chart at nth time common function
        /// </summary>
        /// <param name="isInitial">Flag to recognize that this is the initial time</param>
        /// <param name="daoPerson">Dao Person</param>
        /// <param name="ls">List of person</param>
        /// <param name="lsB">List of person code to keep track which person was already in pedigree chart</param>
        /// <param name="strBuilder">render pedigree string builder</param>
        /// <param name="intGenCount">The number of generation that system rendered. Maximum of this number is 10 default</param>
        /// <param name="intMaxGenDepth">The maximum of generation depth. Default is 10</param>
        /// <returns>pedigree</returns>
        private static string RenderPedigreeNthTime(bool isInitial, DAOPerson daoPerson, List<DAOPerson> ls, List<string> lsB
                                                    , StringBuilder strBuilder, int intGenCount, int intMaxGenDepth = 10)
        {
            if (intGenCount == intMaxGenDepth)
            {
                return strBuilder.ToString();
            }
            if (isInitial)
            {
                strBuilder.AppendLine("<ul>");
                strBuilder.AppendFormat("<li><a href='#divPedigree' name='{0}'>{1}</a>", daoPerson.person_id, daoPerson.person_code);
            }
            bool end = false;
            foreach (DAOPerson person in ls)
            {
                if (BLGenealogic.IsXDescendant(daoPerson.person_code, person.person_code, 1))
                {
                    if (!lsB.Contains(daoPerson.person_code))
                    {
                        lsB.Add(daoPerson.person_code);
                    }
                    if (!end)
                    {
                        strBuilder.AppendLine("<ul>");
                    }
                    strBuilder.AppendFormat("<li><a href='#divPedigree' name='{0}'>{1}</a>", person.person_id, person.person_code);
                    RenderPedigreeNthTime(false, person, ls, lsB, strBuilder, intGenCount + 1, 10);
                    strBuilder.AppendLine("</li>");
                    end = true;
                }
            }
            if (end)
            {
                strBuilder.AppendLine("</ul>");
            }
            if (isInitial)
            {
                strBuilder.AppendLine("</li>");
                strBuilder.AppendLine("</ul>");
            }
            return strBuilder.ToString();
        }
        #endregion Common Function

        #region Render Pedigree
        /// <summary>
        /// Render Pedigree chart at the first time
        /// </summary>
        /// <param name="lsPerson">List of person (members)</param>
        /// <param name="strAction">MVC Action name (optional)</param>
        /// <param name="strController">MVC Controller (optional)</param>
        /// <param name="isAdmin">Permission flag. Default is true</param>
        /// <returns>MvcHtmlString</returns>
        public static MvcHtmlString RenderPedigree(List<DAOPerson> lsPerson, string strAction = null, string strController = null, bool isAdmin = true)
        {
            #region Declare local variables
            StringBuilder strBuilder = new StringBuilder();
            strBuilder.AppendLine("<div id='divPedigree' class='tree content'>");
            StringBuilder strContent = new StringBuilder();
            List<string> lsChild = new List<string>();
            #endregion Declare local variables
            
            try
            {
                #region Validation
                if (lsPerson == null)
                {
                    strBuilder.AppendLine("No members in this family");
                    strBuilder.AppendLine("</div>");
                    return MvcHtmlString.Create(strBuilder.ToString());
                }
                #endregion Validation
                string strResult = RenderPedigree("01", lsPerson, lsChild, strContent, 1, 10);
                strBuilder.Append(strResult);
                strBuilder.AppendLine("<div class='totalScrollOffsetInfo'>Total scroll offset area</div>");
                strBuilder.AppendLine("<div class='totalScrollOffset'></div>");
                strBuilder.AppendLine("</div>");
                return MvcHtmlString.Create(strBuilder.ToString());
            }
            catch (Exception ex)
            {
                strBuilder.Append(ex.Message);
                strBuilder.AppendLine("</div>");
                return MvcHtmlString.Create(strBuilder.ToString());
            }
        }

        /// <summary>
        /// Render Pedigree chart each next time
        /// </summary>
        /// <param name="daoPerson">Current dao person was chosen by user</param>
        /// <param name="lsPerson">List of person (members)</param>
        /// <param name="strAction">MVC Action name (optional)</param>
        /// <param name="strController">MVC Controller (optional)</param>
        /// <param name="isAdmin">Permission flag. Default is true</param>
        /// <returns>MvcHtmlString</returns>
        public static MvcHtmlString RenderPedigree(DAOPerson daoPerson, List<DAOPerson> lsPerson, string strAction = null, string strController = null, bool isAdmin = true)
        {
            #region Declare local variables
            StringBuilder strBuilder = new StringBuilder();
            strBuilder.AppendLine("<div id='divPedigree' class='tree content'>");
            StringBuilder strContent = new StringBuilder();
            List<string> lsChild = new List<string>();
            #endregion Declare local variables

            try
            {
                #region Validation
                if (lsPerson == null)
                {
                    strBuilder.AppendLine("No members in this family");
                    strBuilder.AppendLine("</div>");
                    return MvcHtmlString.Create(strBuilder.ToString());
                }
                #endregion Validation
                string strResult = RenderPedigreeNthTime(true, daoPerson, lsPerson, lsChild, strContent, 1, 10);
                strBuilder.Append(strResult);
                strBuilder.AppendLine("<div class='totalScrollOffsetInfo'>Total scroll offset area</div>");
                strBuilder.AppendLine("<div class='totalScrollOffset'></div>");
                strBuilder.AppendLine("</div>");
                return MvcHtmlString.Create(strBuilder.ToString());
            }
            catch (Exception ex)
            {
                strBuilder.Append(ex.Message);
                strBuilder.AppendLine("</div>");
                return MvcHtmlString.Create(strBuilder.ToString());
            }
        }
        #endregion Render Pedigree
    }
}